package com.vegetable.modules.job;

import com.vegetable.modules.entity.stock.CostWeightChangeSource;
import com.vegetable.modules.service.stock.ICostWeightChangeQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 成本变化分析定时任务
 * </p>
 *
 * @author wangruijie
 * @since 2024-03-21
 */
@Slf4j
@Component
public class CostChangeAnalysisJob {

    @Autowired
    private ICostWeightChangeQueryService costWeightChangeQueryService;

    /**
     * 每天凌晨2点执行成本变化分析
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void analyzeDailyCostChanges() {
        try {
            log.info("开始执行每日成本变化分析任务");

            // 获取昨天的成本变化记录
            List<CostWeightChangeSource> changes = getYesterdayChanges();

            // 分析显著变化
            List<CostWeightChangeSource> significantChanges = costWeightChangeQueryService.querySignificantChanges(new BigDecimal("0.5"));

            // 记录分析结果
            logAnalysisResults(changes, significantChanges);

            log.info("每日成本变化分析任务执行完成");
        } catch (Exception e) {
            log.error("执行每日成本变化分析任务时发生错误", e);
        }
    }

    /**
     * 每周一凌晨3点执行周成本变化趋势分析
     */
    @Scheduled(cron = "0 0 3 * * MON")
    public void analyzeWeeklyCostTrends() {
        try {
            log.info("开始执行周成本变化趋势分析任务");

            // 获取上周的成本变化记录
            List<CostWeightChangeSource> changes = getLastWeekChanges();

            // 分析趋势
            analyzeTrends(changes);

            log.info("周成本变化趋势分析任务执行完成");
        } catch (Exception e) {
            log.error("执行周成本变化趋势分析任务时发生错误", e);
        }
    }

    /**
     * 获取昨天的成本变化记录
     */
    private List<CostWeightChangeSource> getYesterdayChanges() {
        // 这里需要实现具体的查询逻辑
        // 暂时返回空列表
        return Collections.emptyList();
    }

    /**
     * 获取上周的成本变化记录
     */
    private List<CostWeightChangeSource> getLastWeekChanges() {
        // 这里需要实现具体的查询逻辑
        // 暂时返回空列表
        return Collections.emptyList();
    }

    /**
     * 记录分析结果
     */
    private void logAnalysisResults(List<CostWeightChangeSource> allChanges, List<CostWeightChangeSource> significantChanges) {
        log.info("昨日总成本变化记录数: {}", allChanges.size());
        log.info("昨日显著成本变化记录数: {}", significantChanges.size());

        if (!significantChanges.isEmpty()) {
            log.warn("发现显著成本变化记录，详情如下:");
            for (CostWeightChangeSource change : significantChanges) {
                log.warn("商品: {}，变化前: {}，变化后: {}，变化幅度: {}",
                    change.getCommodityName(),
                    change.getBeforeCostWeight(),
                    change.getAfterCostWeight(),
                    change.getChangeAmount());
            }
        }
    }

    /**
     * 分析趋势
     */
    private void analyzeTrends(List<CostWeightChangeSource> changes) {
        if (changes.isEmpty()) {
            log.info("上周无成本变化记录");
            return;
        }

        log.info("上周成本变化趋势分析:");
        log.info("总变化记录数: {}", changes.size());

        // 计算平均变化幅度
        BigDecimal totalChange = changes.stream()
            .map(CostWeightChangeSource::getChangeAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal averageChange = totalChange.divide(new BigDecimal(changes.size()), 6, BigDecimal.ROUND_HALF_UP);

        log.info("平均变化幅度: {}", averageChange);

        // 统计各类变化类型的数量
        long orderChanges = changes.stream()
            .mapToInt(CostWeightChangeSource::getSourceType)
            .filter(type -> type == 1)
            .count();

        long inboundChanges = changes.stream()
            .mapToInt(CostWeightChangeSource::getSourceType)
            .filter(type -> type == 2)
            .count();

        long feeChanges = changes.stream()
            .mapToInt(CostWeightChangeSource::getSourceType)
            .filter(type -> type == 3)
            .count();

        long chainChanges = changes.stream()
            .mapToInt(CostWeightChangeSource::getSourceType)
            .filter(type -> type == 4)
            .count();

        log.info("订单价格修改引起的变更: {}次", orderChanges);
        log.info("入库调整引起的变更: {}次", inboundChanges);
        log.info("费用分摊引起的变更: {}次", feeChanges);
        log.info("连锁反应引起的变更: {}次", chainChanges);

        log.info("本周成本变化分析完成，时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }
}